package sixkey.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import sixkey.Exception.PasswordErrorException;
import sixkey.Exception.UserIsDeletedException;
import sixkey.Exception.UserNameExistException;
import sixkey.Exception.UserNameNotFoundException;
import sixkey.annotation.PermissionAnnotation;
import sixkey.domain.entity.User;
import sixkey.domain.vo.UserVo;
import sixkey.service.IUserService;
import sixkey.utils.ResCodeEnum;
import sixkey.utils.ResResult;
import sixkey.utils.SMSUtils;
import sixkey.utils.ValidateCodeUtils;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

/**
 * ClassName:controller
 * Package:sixkey
 * Description
 *
 * @Author:@wenxueshi
 * @Create:2023/5/19 - 22:09
 * @Version:v1.0
 */
@Slf4j
@Api(tags = "系统用户管理接口")
@RestController
@RequestMapping("/users")
//lombok提供的自动注入注解，但是被注入属性要加final修饰
@RequiredArgsConstructor
//参数校验
@Validated
public class UserController {

    //已经通过@RequiredArgsConstructor此注解自动注入值
    private final IUserService userService;

    //用户注册
    @ApiOperation(value = "用户注册", httpMethod = "POST",response = ResResult.class, notes = "用户注册")
    @PostMapping("/registry")
    public ResResult RegisterUser(@RequestBody @Valid User user) throws UserNameExistException {
        log.info("==== {}用户注册请求进来了 =====",user.getUsername());
        userService.RegisterUser(user);
        return ResResult.okResult();
    }

    //用户登录
    @ApiOperation(value = "用户登录", httpMethod = "POST", response = ResResult.class, notes = "用户登录")
    @PostMapping("/login")
    public ResResult doLogin(@RequestBody UserVo loginUserVo) throws UserNameNotFoundException, PasswordErrorException {
        userService.doLogin(loginUserVo);
        //返回token值
        return ResResult.okResult(StpUtil.getTokenValue());
    }

    //修改用户
    @SaCheckLogin
    @SaCheckRole("admin")
    @SaCheckPermission("system/user/update")
    @ApiOperation(value = "修改用户",httpMethod = "PUT",response = ResResult.class,notes = "修改用户")
    @PutMapping("/update")
    public ResResult updateUser(@RequestBody @Valid User user){
        // 检验当前会话是否已经登录, 如果未登录，则抛出异常：`NotLoginException`
        StpUtil.checkLogin();
        log.info("修改用户请求进来了.............");
        userService.updateUser(user);
        return ResResult.okResult();
    }

    //根据id获取用户
    @ApiOperation(value = "根据id获取用户")
    @GetMapping("/getById/{id}/{username}")
    @PermissionAnnotation(value = "校验id是否合法或者用户是否是管理员") //aop权限校验
    public ResResult getById(@PathVariable("id") Long id,@PathVariable("username") String username){
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getId,id);
        wrapper.eq(User::getUsername,username);
        User user = userService.getOne(wrapper);
        return ResResult.okResult(user);
    }

    //删除用户
    @SaCheckLogin //登录校验 —— 只有登录之后才能进入该方法。
    @ApiOperation(value = "删除用户",httpMethod = "DELETE",response = ResResult.class,notes = "删除用户")
    @DeleteMapping("/delete/{id}")
    @SaCheckPermission("system/user/delete")
    public ResResult updateUser(@PathVariable("id") Long id){
        log.info("删除用户请求进来了.................");
        userService.removeById(id);
        return ResResult.okResult();
    }

    //修改用户状态
    @ApiOperation(value = "修改用户状态",httpMethod = "PUT",response = ResResult.class,notes = "修改用户状态")
    @PutMapping("/update/{id}/{status}")
    public ResResult updateUserStatus(@PathVariable("id") Long id,
                                      @PathVariable("status") Long status) throws UserIsDeletedException {
        log.info("修改用户状态请求进来了.............");
        userService.updateUserStatus(id,status);
        return ResResult.okResult();
    }

    // 查询登录状态，浏览器访问： http://localhost:8081/users/isLogin
    @ApiOperation(value = "查询登录状态",httpMethod = "GET",response = String.class,notes = "查询登录状态")
    @GetMapping("/isLogin")
    public String isLogin() {
        return "当前会话是否登录：" + StpUtil.isLogin();
    }

    // 查询登录状态，浏览器访问： http://localhost:8081/users/isLogin
    @ApiOperation(value = "退出登录",httpMethod = "GET",response = ResResult.class,notes = "退出登录")
    @GetMapping("/loginOut")
    public ResResult loginOut() {
        StpUtil.logout();
        return ResResult.okResult();
    }

    // 查询Token信息  ---- http://localhost:8081/acc/tokenInfo
    @ApiOperation(value = "查询Token信息",httpMethod = "GET",response = ResResult.class,notes = "查询Token信息")
    @GetMapping("/tokenInfo")
    public ResResult tokenInfo() {
        return ResResult.okResult(StpUtil.getTokenInfo());
    }

    @SaCheckLogin
    @SaIgnore
    @ApiOperation(value = "验证码登录",httpMethod = "POST",response = ResResult.class,notes = "验证码登录")
    @PostMapping("/sendMsg")
    public ResResult sendMsg(@RequestBody @Valid UserVo userVo, HttpServletRequest request) throws Exception {
        //获取手机号
        String phone = userVo.getPhone();
        if(!StringUtils.isEmpty(phone)){
            //生成随机的4位验证码
            String code = ValidateCodeUtils.generateValidateCode(4).toString();
            //调用阿里云提供的短信服务API完成发送短信
            SMSUtils.sendMessage("文学博客","SMS_460736247",phone,code);
            //需要将生成的验证码保存到Session
            //request.getSession().setAttribute(phone,code);
            return ResResult.okResult(code);
        }
        return ResResult.errorResult(ResCodeEnum.SYSTEM_ERROR,"短信发送失败");
    }
}
